namespace ETestIT.Tests.DataAccess
{
    using System;
    using System.Configuration;
    using System.Data;
    using System.Data.SqlClient;
    using System.IO;
    using System.Reflection;
    using Core;
    using NUnit.Framework;

    [TestFixture]
    public class DbSetupTestFixture
    {
        private readonly string configConnStr =
            ConfigurationManager.ConnectionStrings[Const.ConnectionStringName].ConnectionString;

        private string GetDataBaseNameFromConnectionString(string theConfigConnStr)
        {
            return theConfigConnStr
                .Split(';')[1]
                .Split('=')[1];
        }

        private string PrepareMasterConnStr(string theConfigConnStr)
        {
            var userDbName = GetDataBaseNameFromConnectionString(theConfigConnStr);
            return theConfigConnStr.Replace(userDbName, "master");
        }

        private string GetEmbeddedResourceStringContent(string resourceName)
        {
            const string assemblyName = "ETestIT.DataBase.";

            var dbAssembly = Assembly.LoadFrom(assemblyName + "dll");
            var sr = new StreamReader(dbAssembly.GetManifestResourceStream(assemblyName + resourceName));

            return sr.ReadToEnd();
        }

        [Test]
        public void IsPossibleToBuildConnectToTheMasterFromUserConfStr()
        {
            string mastConnStr = PrepareMasterConnStr(configConnStr);
            using (var connection = new SqlConnection(mastConnStr))
            {
                connection.Open();
                Assert.That(connection.State == ConnectionState.Open);
            }
        }

        [Test]
        public void ShouldProveThatresourcesFormDataBaseAssemblyAreReachble()
        {
            Assert.That(GetEmbeddedResourceStringContent("0Cleanup.sql"), Is.Not.Empty);
        }

        [Test]
        public void ShouldAsureThatConnectionStringIsProvided()
        {
            Assert.That(configConnStr, Is.Not.Empty);
        }

        [Test, Ignore]
        public void ShouldCreateDataBaseStructureFromScripts()
        {
            var originalDbName = GetDataBaseNameFromConnectionString(configConnStr);

            using (var conn = new SqlConnection(PrepareMasterConnStr(configConnStr)))
            {
                var command = new SqlCommand {Connection = conn};

                conn.Open();

                command.CommandText = GetEmbeddedResourceStringContent("0Cleanup.sql")
                    .Replace("@DB_NAME", originalDbName);
                command.ExecuteNonQuery();

                conn.ChangeDatabase(originalDbName);

                command.CommandText = GetEmbeddedResourceStringContent("1Tabeles.sql");
                command.ExecuteNonQuery();

                command.CommandText = GetEmbeddedResourceStringContent("2SetUpData.sql");
                command.ExecuteNonQuery();

                command.CommandText = GetEmbeddedResourceStringContent("fn_hexstrtovarbin.sql");
                command.ExecuteNonQuery();

                command.CommandText = GetEmbeddedResourceStringContent("3TestData.sql");
                command.ExecuteNonQuery();

                Console.WriteLine("Database was created with success !!!");
            }
        }
    }
}